﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Infrastructure.Crosscutting.Authorize
{
    public class InitPermissionService : IInitPermissionService
    {
        IMvcActionService actionService;

        IMvcActionClassService actionClassService;

        IMvcControllerService controllerService;

        IMvcControllerClassService controllerClassService;

        AssemblyPermissionService assemblyPermissionService;

        //--------------------------------------------------------
        Infrastructure.Crosscutting.Authorize.IUserService userService;

        Infrastructure.Crosscutting.Authorize.IRoleService roleService;

        Infrastructure.Crosscutting.Authorize.IUserRoleService userRoleService;

        Infrastructure.Crosscutting.Authorize.IMvcRolePermissionService rolePermissionService;

        public InitPermissionService(IMvcActionService action,
            IMvcControllerClassService controllerClass,
            IMvcControllerService controller,
            IMvcActionClassService actionClass,
            AssemblyPermissionService assemblyController,
            IUserService user, IRoleService role,
            IUserRoleService userRole, IMvcRolePermissionService rolePermission)
        {
            if (action == null)
            {
                throw new ArgumentNullException("actionService is null");
            }
            if (actionClass == null)
            {
                throw new ArgumentNullException("actionClassService is null");
            }
            if (controllerClass == null)
            {
                throw new ArgumentNullException("controllerClassService is null");
            }
            if (controller == null)
            {
                throw new ArgumentNullException("actionService is null");
            }
            if (assemblyController == null)
            {
                throw new ArgumentNullException("assemblyControllerService is null");
            }

            if (user == null)
            {
                throw new ArgumentNullException("userService is null");
            }
            if (role == null)
            {
                throw new ArgumentNullException("roleService is null");
            }
            if (userRole == null)
            {
                throw new ArgumentNullException("userRoleService is null");
            }
            if (rolePermission == null)
            {
                throw new ArgumentNullException("rolePermissionService is null");
            }
            actionService = action;
            actionClassService = actionClass;
            controllerService = controller;
            controllerClassService = controllerClass;
            assemblyPermissionService = assemblyController;
            userService = user;
            roleService = role;
            userRoleService = userRole;
            rolePermissionService = rolePermission;
        }

        public List<Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto> GetInstalledPermission()
        {
            var allPermission = new List<Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto>();
            var allController = controllerService.GetList();
            foreach (var item in allController)
            {
                var controllerAction = actionService.GetList().Where(e => e.ControllerId == item.Id);
                var controllerClass = controllerClassService.GetList().Where(e => e.Id == item.ClassId).FirstOrDefault();
                foreach (var action in controllerAction)
                {
                    if (action.State)
                    {
                        var model = new Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto();
                        model.ActionClassId = action.ClassId;
                        var actionClassName = actionClassService.GetList().Where(e => e.Id == action.ClassId).FirstOrDefault();
                        model.ActionClassName = (actionClassName != null && actionClassName.Name != null) ? actionClassName.Name : "权限没有分类";
                        model.ActionId = action.Id;
                        model.ActionName = action.Name;
                        model.ActionRemark = action.Remark;
                        model.ControllerClassId = item.ClassId;
                        model.ControllerClassName = controllerClass != null ? controllerClass.Name : "控制器没有分类";
                        model.ControllerId = item.Id;
                        model.ControllerName = item.Name;
                        model.ControllerRemark = item.Remark;
                        allPermission.Add(model);
                    }
                }
            }
            return allPermission.OrderByDescending(e => e.ActionId).ToList();
        }

        public List<Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto> GetUninstallPermission()
        {
            var installed = GetInstalledPermission();
            var allPermission = assemblyPermissionService.GetAssemblyAllPermission("Presentation.Web.Admin");
            var uninstall = new List<Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto>();
            foreach (var item in allPermission)
            {
                if (!installed.Where(e => e.ActionName.Trim() == item.ActionName.Trim() && e.ControllerName.Trim() == item.ControllerName.Trim()).Any())
                {
                    uninstall.Add(item);
                }
            }
            return uninstall;
        }

        public bool AddAssemblyPermissionToDb()
        {
            var res = false;
            var autoControllerInfo = assemblyPermissionService.GetAssemblyControllerInfo("Presentation.Web.Admin");
            var defaultUser = userService.GetDefautlOperUser();
            var actionClassList = actionClassService.GetList().ToList();
            var controllerClassList = controllerClassService.GetList().ToList();
            try
            {
                #region controller

                foreach (var item in autoControllerInfo)
                {
                    var oldController = controllerService.GetList().Where(e => e.AssemblyFullName == item.ContorllerType.FullName).Any();
                    if (!oldController)
                    {
                        var controller = new Domain.Entity.MvcController();
                        controller.AddTime = System.DateTime.Now;
                        controller.AssemblyFullName = item.ContorllerType.FullName;

                        #region cla

                        var pre = item.ContorllerType.FullName.Split('.');
                        var name = pre[pre.Length - 1];
                        name = string.IsNullOrEmpty(name) ? "" : name.ToLower().Replace("controller", "");
                        var cla = 0;
                        if (pre.Contains("Open"))
                        {
                            cla = controllerClassList.Where(e => e.Remark.ToLower().IndexOf(name) >= 0)
                                .Where(e => e.Remark.ToLower().IndexOf("interface") >= 0)
                                .Select(e => e.Id).FirstOrDefault();
                        }
                        else
                        {
                            cla = controllerClassList.Where(e => e.Remark.ToLower().IndexOf(name) >= 0)
                                .Where(e => e.Remark.ToLower().IndexOf("interface") < 0)
                                .Select(e => e.Id).FirstOrDefault();
                        }
                        controller.ClassId = cla;

                        #endregion


                        controller.Id = 0;
                        controller.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                        controller.Name = item.ContorllerType.FullName;
                        controller.Remark = item.ContorllerType.FullName;
                        controller.SortNum = 0;
                        controller.State = true;
                        controllerService.Add(controller, defaultUser);
                    }
                }
                #endregion

                #region action

                foreach (var item in autoControllerInfo)
                {
                    foreach (var it in item.ActionList)
                    {
                        var action = new Domain.Entity.MvcAction();
                        var parentContorller = controllerService.GetList()
                            .Where(e => e.AssemblyFullName == item.ContorllerType.FullName).FirstOrDefault();
                        if (parentContorller != null && parentContorller.Id > 0)
                        {
                            var oldAction = actionService.GetList().Where(e => e.Name == it && e.ControllerId == parentContorller.Id).Any();
                            if (!oldAction)
                            {
                                action.AddTime = System.DateTime.Now;
                                action.ControllerId = parentContorller.Id;
                                action.Id = 0;

                                #region cla

                                var pre = item.ContorllerType.FullName.Split('.');
                                var name = pre[pre.Length - 1];
                                name = string.IsNullOrEmpty(name) ? "" : name.ToLower().Replace("controller", "");
                                var cla = 0;
                                if (pre.Contains("Open"))
                                {
                                    cla = actionClassList.Where(e => e.Remark.ToLower().IndexOf(name) >= 0)
                                        .Where(e => e.Remark.ToLower().IndexOf("interface") >= 0)
                                        .Select(e => e.Id).FirstOrDefault();
                                }
                                else
                                {
                                    cla = actionClassList.Where(e => e.Remark.ToLower().IndexOf(name) >= 0)
                                        .Where(e => e.Remark.ToLower().IndexOf("interface") < 0)
                                        .Select(e => e.Id).FirstOrDefault();
                                }

                                action.ClassId = cla;

                                #endregion

                                action.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                                action.Name = it;
                                action.Remark = it;
                                action.SortNum = 0;
                                action.State = true;
                                actionService.Add(action, defaultUser);
                            }
                        }
                    }
                }

                #endregion

                res = true;
            }
            catch (Exception ex)
            {
            }
            return res;
        }

        public bool InitAdminPermission(string message)
        {
            var res = false;

            if (actionService.GetList().Any())
            {
                var adminIdList = (from user in userService.GetList()
                                   join userRole in userRoleService.GetList() on user.Id equals userRole.UserId
                                   join role in roleService.GetList() on userRole.RoleId equals role.Id
                                   where role.Remark.IndexOf("supper") >= 0
                                   select new { userId = user.Id, roleId = role.Id }).ToList();
                if (adminIdList.Any())
                {
                    foreach (var item in adminIdList)
                    {
                        var allPermission = actionService.GetList().ToList();
                        foreach (var per in allPermission)
                        {
                            if (!rolePermissionService.GetList().Where(e => e.RoleId == item.roleId && e.ActionId == per.Id).Any())
                            {
                                var temp = new Domain.Entity.MvcRolePermission()
                                {
                                    ActionId = per.Id,
                                    AddTime = System.DateTime.Now,
                                    //Id
                                    IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP(),
                                    Name = per.Name,
                                    Remark = per.Remark,
                                    RoleId = item.roleId,
                                    SortNum = 0,
                                    State = per.State
                                };
                                rolePermissionService.Add(temp, userService.GetDefautlOperUser());
                            }
                        }
                    }
                    res = true;
                }
                else
                {
                    message = "貌似没有找到一个用户为超级管理员T_T";
                }
            }
            else
            {
                message = "貌似没有任何权限可以安装的，你可以初始化一下权限试试";
            }
            return res;
        }

        public bool InitSystemUserPermission(string message)
        {
            var res = false;
            if (actionService.GetList().Any())
            {
                var systemIdList = (from user in userService.GetList()
                                    join userRole in userRoleService.GetList() on user.Id equals userRole.UserId
                                    join role in roleService.GetList() on userRole.RoleId equals role.Id
                                    where role.Remark.IndexOf("system") >= 0
                                    select new { userId = user.Id, roleId = role.Id }).ToList();
                if (systemIdList.Any())
                {
                    var excepted = new string[]{
                    "Presentation.Web.Admin.Controllers.UserRoleController",
                    "Presentation.Web.Admin.Controllers.LoggerController",
                    "Presentation.Web.Admin.Controllers.UserController",
                    "Presentation.Web.Admin.Controllers.RoleController",
                    "Presentation.Web.Admin.Controllers.PermissionController"};
                    var exceptedIdList = controllerService.GetList().Where(e => excepted.Contains(e.AssemblyFullName))
                        .Select(e => e.Id);
                    foreach (var item in systemIdList)
                    {
                        var allPermission = actionService.GetList().Where(e => !exceptedIdList.Contains(e.ControllerId)).ToList();
                        foreach (var per in allPermission)
                        {
                            if (!rolePermissionService.GetList().Where(e => e.RoleId == item.roleId && e.ActionId == per.Id).Any())
                            {
                                var temp = new Domain.Entity.MvcRolePermission()
                                {
                                    ActionId = per.Id,
                                    AddTime = System.DateTime.Now,
                                    //Id
                                    IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP(),
                                    Name = per.Name,
                                    Remark = per.Remark,
                                    RoleId = item.roleId,
                                    SortNum = 0,
                                    State = per.State
                                };
                                rolePermissionService.Add(temp, userService.GetDefautlOperUser());
                            }
                        }
                    }
                    res = true;
                }
                else
                {
                    message = "貌似没有找到一个用户为超级管理员T_T";
                }
            }
            else
            {
                message = "貌似没有任何权限可以安装的，你可以初始化一下权限试试";
            }
            return res;
        }


        public bool InitOpenUserPermission(string message)
        {
            var res = false;
            if (actionService.GetList().Any())
            {
                var systemIdList = (from user in userService.GetList()
                                    join userRole in userRoleService.GetList() on user.Id equals userRole.UserId
                                    join role in roleService.GetList() on userRole.RoleId equals role.Id
                                    where role.Remark.IndexOf("interface") >= 0
                                    select new { userId = user.Id, roleId = role.Id }).ToList();
                if (systemIdList.Any())
                {
                    var excepted = new string[]{
                    "Presentation.Web.Admin.Areas.Open.Controllers.TourController",
                    "Presentation.Web.Admin.Areas.Open.Controllers.SightController",
                    "Presentation.Web.Admin.Areas.Open.Controllers.PicController",
                    "Presentation.Web.Admin.Areas.Open.Controllers.HomeController",
                    "Presentation.Web.Admin.Areas.Open.Controllers.ClientController",
                    "Presentation.Web.Admin.Areas.Open.Controllers.ArticleController"};
                    var includeIdList = controllerService.GetList().Where(e => excepted.Contains(e.AssemblyFullName))
                        .Select(e => e.Id);
                    foreach (var item in systemIdList)
                    {
                        var allPermission = actionService.GetList().Where(e => includeIdList.Contains(e.ControllerId)).ToList();
                        foreach (var per in allPermission)
                        {
                            if (!rolePermissionService.GetList().Where(e => e.RoleId == item.roleId && e.ActionId == per.Id).Any())
                            {
                                var temp = new Domain.Entity.MvcRolePermission()
                                {
                                    ActionId = per.Id,
                                    AddTime = System.DateTime.Now,
                                    //Id
                                    IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP(),
                                    Name = per.Name,
                                    Remark = per.Remark,
                                    RoleId = item.roleId,
                                    SortNum = 0,
                                    State = per.State
                                };
                                rolePermissionService.Add(temp, userService.GetDefautlOperUser());
                            }
                        }
                    }
                    res = true;
                }
                else
                {
                    message = "貌似没有找到一个用户为超级管理员T_T";
                }
            }
            else
            {
                message = "貌似没有任何权限可以安装的，你可以初始化一下权限试试";
            }
            return res;
        }
    }
}
